﻿using NLog;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.ComponentModel.Composition.Hosting;
using System.ComponentModel.Composition;
using System.Configuration;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.IO;
using HotFolderService.Loggers;

namespace HotFolderService
{
    public partial class HotFolderService : ServiceBase
    {
        public HotFolderService()
        {
            InitializeComponent();
        }

        
        HotFolderServiceInterface.ILogger logger = null;
        
        protected override void OnStart(string[] args)
        {
            // TODO resolve this. 
            logger = new NLogLogger();
            logger.Trace("HotFolder Service started");

            var hotfolderCollection = GetHotFolderCollection();
            if (hotfolderCollection != null)
            {
                foreach (HotFolderElement element in hotfolderCollection)
                {
                    System.IO.FileSystemWatcher fileSystemWatcher = new System.IO.FileSystemWatcher();
                    fileSystemWatcher.Path = element.Path;
                    fileSystemWatcher.EnableRaisingEvents = true;
                    fileSystemWatcher.NotifyFilter = System.IO.NotifyFilters.FileName | System.IO.NotifyFilters.DirectoryName;
                    fileSystemWatcher.Created += new System.IO.FileSystemEventHandler(this.fileSystemWatcher1_Created);

                }
            }
        }

        private HotFolderCollection GetHotFolderCollection()
        {
            var hotfoldersection = ConfigurationManager.GetSection(HotFolderConfigSection.sectionName) as HotFolderConfigSection;
            if (hotfoldersection != null)
            {
                return hotfoldersection.FoldersToWatch;
            }
            return null;
        }
    

        protected override void OnStop()
        {
        }

       
        private void fileSystemWatcher1_Created(object sender, System.IO.FileSystemEventArgs e)
        {
            try
            {
                var fsw = sender as FileSystemWatcher;
                if (fsw == null) return;

                var plugins = Plugins.list;
                var hotfolderCollection = GetHotFolderCollection();
                

                
                String customsection = "";
                HotFolderServiceInterface.IHotFolderType foldertype = null;

                foreach (HotFolderElement hotfolder in hotfolderCollection)
                {
                    if (hotfolder.Path == fsw.Path)
                    {
                        foldertype = plugins.Where(u => u.HotFolderTypeName == hotfolder.HotFolderType).FirstOrDefault();
                        customsection = hotfolder.CustomSection;
                        break;
                    }
                }


                if (foldertype == null)
                {
                    logger.Trace("Could not find the plugin, stopping the service");
                    return;
                }

                logger.Trace(String.Format("Processing file {0} for {1}", e.FullPath, foldertype.HotFolderTypeName));

                NameValueCollection settings = null;
                
                if (!(String.IsNullOrEmpty(customsection)))
                {
                    settings = ConfigurationManager.GetSection(String.Format("{0}/appSettings", customsection)) as NameValueCollection;
                }

                foldertype.Execute(e.Name, e.FullPath, settings);

                logger.Trace(String.Format("Done Processing file {0} for {1}", e.FullPath, foldertype.HotFolderTypeName));

                try
                {
                    System.IO.File.Delete(e.FullPath);
                }
                catch { }
            }
            catch (Exception ex)
            {
                logger.Exception(ex);
            }
           
        }

        

        private HotFolderPlugins Plugins
        {
            get
            {
                // Initialise the catalog, iterate through the plugins folder
                var catalog = new AggregateCatalog();
                catalog.Catalogs.Add(new DirectoryCatalog("Tasks"));
                catalog.Catalogs.Add(new DirectoryCatalog("."));
                catalog.Catalogs.Add(new AssemblyCatalog(typeof(Program).Assembly));

                // prepare batch 
               
                // Prepare container
                var container = new CompositionContainer(catalog);
                container.ComposeExportedValue("Logger", logger);
                // Prepare plugin list
                var plugins = new HotFolderPlugins();
                
                plugins.list = container.GetExportedValues<HotFolderServiceInterface.IHotFolderType>();
                return plugins;
            }
        }

    }
}
